package com.example.ibsp_demo.service.impl;

import com.example.ibsp_demo.mapper.login.VerificationCodeMapper;
import com.example.ibsp_demo.mapper.user.UserMapper;
import com.example.ibsp_demo.pojo.dto.login.LoginDto;
import com.example.ibsp_demo.pojo.dto.login.RegisterDto;
import com.example.ibsp_demo.pojo.dto.login.ResetDto;
import com.example.ibsp_demo.pojo.entity.login.VerificationCode;
import com.example.ibsp_demo.pojo.entity.user.User;
import com.example.ibsp_demo.service.ILoginService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;

import static com.example.ibsp_demo.utils.PasswordUtils.hashPassword;
import static com.example.ibsp_demo.utils.PasswordUtils.verifyPassword;

@Service
public class LoginService implements ILoginService {


    @Autowired
    UserMapper userMapper ;

    @Autowired
    VerificationCodeMapper codeMapper;




    @Override
    public Boolean login(LoginDto loginDto) {
        String password = loginDto.getPassword();
        User  user = get(loginDto.getUserInput());
        try {
            return  verifyPassword(password,user.getPasswordHash());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public User get(String userInput) {
        //识别userInput是 用户名 ？ 手机号 ？ 邮箱 ？（看来还要在库里设置唯一）


        User user = null;
        //DEBUG:过这里了

        if(userInput.contains("@")){
            //邮箱登录
            user = userMapper.selectByEmail(userInput);

        }else if(userInput.length() == 11){
            //手机号登录
            user = userMapper.selectByPhone(userInput);

        }else{
            //用户名登录

            user = userMapper.selectByUsername(userInput);
            //DEBUG:来过这里
        }

        return user;
    }

    @Override
    public Boolean register(RegisterDto dto) {
        //先检测输入数据是否正确有效 + 是否没有重复

        //实现来自萨比前端的攻击设立的保护机制
        if(dto.getUserName() == null || dto.getPassword() == null || dto.getEmail() == null){
            return false;
        }


        //用户名 > 2 且不包含空字符 且 没人取过这个名字
        if( !isValidInput(dto.getUserName()) || get(dto.getUserName()) != null ) {
            return false;
        }
        // email检测机制
        if (!isValidInput(dto.getEmail()) ||!dto.getEmail().contains("@") || get(dto.getEmail())!=null) {
            return false;
        }

        //密码要检测包含大小写字母和数字,检查密码长度是前端的事 ，不能为空也是前端的事
        if (dto.getPassword().length() < 6) {
            return false;
        }

        //全部检测成功后执行插入操作
        try {
            User newUser = new User(null,dto.getUserName(),dto.getEmail(),null,hashPassword(dto.getPassword()),1, LocalDateTime.now(),LocalDateTime.now());
            userMapper.insert(newUser);
            return true;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

    }

    @Override
    public Boolean reset(ResetDto dto) {
        // 1. 先检查用户是否存在
        User user = get(dto.getUserInput());
        if (user == null) {
            return false; // 用户不存在，直接返回失败
        }

        // 插入此处：验证码验证逻辑
        // 2. 验证验证码是否有效（未过期、未使用、匹配）
        // 2.1 定义验证码类型（重置密码）和当前时间
        String codeType = "reset"; // 区分是注册/登录/重置密码的验证码
        LocalDateTime now = LocalDateTime.now();

        // 2.2 查询数据库中符合条件的验证码：目标一致、类型一致、未使用、未过期
        VerificationCode validCode = codeMapper.selectValidCode(
                dto.getUserInput(),  // 目标（邮箱）
                codeType,            // 验证码类型（重置密码）
                0,                   // is_used=0（未使用）
                now                  // 过期时间>当前时间（未过期）
        );

        // 2.3 验证验证码是否存在且匹配
        if (validCode == null || !validCode.getCode().equals(dto.getVerifyCode())) {
            return false; // 验证码无效或不匹配
        }

        // 2.4 验证通过，标记验证码为已使用（防止重复使用）
        validCode.setIsUsed(1);
        codeMapper.update(validCode);

        // 3. 验证码通过，重置密码
        try {
            user.setPasswordHash(hashPassword(dto.getPassword()));
            userMapper.updateByUser(user);
            return true; // 重置成功
        } catch (Exception e) {
            throw new RuntimeException("密码重置失败", e);
        }
    }

    @Override
    public Boolean checkAdmin(LoginDto dto) {
        return "admin".equals(dto.getUserInput()) && "123456".equals(dto.getPassword());
    }

    private boolean isValidInput(String input) {
        return input != null
                && input.length() > 2
                && !input.contains(" ")
                && !input.contains("\t")
                && !input.contains("\n");
    }
}
